#include <iostream>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <cstring>

using namespace std;

int main()
{
    int spi_fd;
    int ret;

    //使用SPI1接口
    spi_fd = open("/dev/spidev0.0", O_RDWR);
    if (spi_fd < 0) {
        perror("Error: Cann't open SPI Dev.\n");
        return -1;
    }

    //配置SPI参数
    uint32_t speed = 4000000;
    uint16_t delay = 0;
    uint8_t bits_per_word = 8;
    uint8_t mode = 0;
    ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &mode);
    if (ret == -1) {
        perror("Error: SPI_IOC_WR_MODE fault.\n");
        return -1;
    }

    ret = ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
    if (ret == -1) {
        perror("Error: SPI_IOC_WR_BITS fault.\n");
        return -1;
    }

    ret = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1) {
        perror("Error: SPI_IOC_WR_MAX_SPEED fault.\n");
        return -1;
    }

    //发送数据
    char tx_buf[1] = {0x01};
    char rx_buf[32] = {};
    struct spi_ioc_transfer spi { };
    spi.tx_buf = (unsigned long)tx_buf;
    spi.rx_buf = (unsigned long)rx_buf;
    spi.len = sizeof(tx_buf);
    spi.delay_usecs = delay;
    spi.speed_hz = speed;
    spi.bits_per_word = bits_per_word;
    // Send wr_addr
    ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
    if (ret < 1) {
        perror("Error: SPI_IOC_MESSAGE fault.\n");
        return -1;
    }
    else {
        printf("addr recva: 0x%x\n", rx_buf[0]);
    }

    // close(spi_fd);
    printf("transmit suc!\n");
    uint16_t id = 0x01;

    spi.tx_buf = (unsigned long)&id;
    spi.rx_buf = (unsigned long)rx_buf;
    spi.len = 2;
    // Read CAN-ID
    ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
    if (ret < 1) 
    {
        perror("Error");
    }
    else
    {
        printf("id_rcv: 0x%x\n", rx_buf[0]);
    }

    printf("transmit suc!\n");
    uint8_t len = 20;
    spi.tx_buf = (unsigned long)&len;
    spi.rx_buf = (unsigned long)rx_buf;
    spi.len = 1;
    // Read length
    ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
    if (ret < 1)
    {
        perror("Error");
    }
    else
    {
        printf("len_recv: 0x%x\n", rx_buf[0]);
    }

    printf("transmit suc!\n");
    uint8_t fdcan_data[] = {0x01, 0x00, 0x0A, 0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x04, 0x00};

    spi.tx_buf = (unsigned long)fdcan_data;
    spi.rx_buf = (unsigned long)rx_buf;
    spi.len = rx_buf[0];
    fdcan_data[0] = spi.len;
    if(spi.len != 0)
    {
        // Read Message
        ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
        if (ret < 1)
        {  
            perror("Error");
        }
        else
        {
            printf("msg: ");
	    for(uint8_t i = 0; i < fdcan_data[0]; i++)
	    {
                printf("0x%02x,", rx_buf[i]);
	    }
	    printf("\b\n");
        }  
    }
    else
    {
	printf("No data\n");
    }
    close(spi_fd);
    return 0;
}

